package com.astronomia.wheels.tree_explore;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName : DukeWeiTest
 * @Description : 三级节点树形结构测试
 * @Author : DukeWei
 * @Date : 2021/4/25 16:48
 * @Version : 1.0
 **/
public class DukeWeiTest {

    public static List<NodeEntity> getNodeEntityList() {
        List<NodeEntity> list = new ArrayList<>();
//        list.add(new NodeEntity(1L, null, null));
//        list.add(new NodeEntity(2L, 1L, 1L));
//        list.add(new NodeEntity(3L, 1L, 1L));
//        list.add(new NodeEntity(4L, 1L, 2L));
//        list.add(new NodeEntity(5L, 1L, 2L));
//        list.add(new NodeEntity(6L, 1L, 3L));
//        list.add(new NodeEntity(7L, 1L, 3L));
//        list.add(new NodeEntity(8L, null, null));
//        list.add(new NodeEntity(9L, 8L, 8L));
//        list.add(new NodeEntity(10L, 8L, 8L));
//        list.add(new NodeEntity(11L, 8L, 8L));
        for (long i = 1L; i < 10000000; i++) {
            int topParentId = (int) (Math.random() * 10);
            long topParentIdLong = topParentId;
            if (topParentIdLong == 0) {
                topParentIdLong = 1;
            }
            int parentId = (int) (Math.random() * 100);
            long parentIdLong = parentId;
            if (parentIdLong == 0) {
                parentIdLong = 11;
            }

            if (i < 11) {
                list.add(new NodeEntity(i, null, null));
            } else if (i < 101) {
                list.add(new NodeEntity(i, topParentIdLong, topParentIdLong));
            } else {
                list.add(new NodeEntity(i, topParentIdLong, parentIdLong));
            }
        }
        return list;
    }

    public static void main(String[] args) {
        List<NodeEntity> nodeEntityList = getNodeEntityList();
//        nodeAlgorithmOne(nodeEntityList);
        nodeAlgorithmTwo(nodeEntityList);
    }

    private static void nodeAlgorithmOne(List<NodeEntity> nodeEntityList) {
        Long start = System.currentTimeMillis();
        Map<Long, List<NodeEntity>> collect = nodeEntityList.stream().collect(Collectors.groupingBy(NodeEntity::getId));
        nodeEntityList.forEach(e -> {
            if (e.getParentId() != null && collect.containsKey(e.getParentId())) {
                List<NodeEntity> nodeEntityList1 = collect.get(e.getParentId()).get(0).getNodeEntityList();
                nodeEntityList1.add(e);
                collect.get(e.getParentId()).get(0).setNodeEntityList(nodeEntityList1);
            }
        });

        List<NodeEntity> nodeEntities = nodeEntityList.stream().filter(e -> e.getTopParentId() == null).collect(Collectors.toList());
        Long end = System.currentTimeMillis();
//        for (NodeEntity nodeEntity : nodeEntities) {
//            System.out.println(nodeEntity);
//        }
        long time = end - start;
        System.out.println("nodeAlgorithmOne is time : " + time);
    }

    private static void nodeAlgorithmTwo(List<NodeEntity> nodeEntityList) {

        Long start = System.currentTimeMillis();

        List<NodeEntity> nodeEntityListOne = nodeEntityList.stream().filter(e -> e.getParentId() == null && e.getTopParentId() == null).collect(Collectors.toList());

        List<NodeEntity> nodeEntityListTwo = nodeEntityList.stream().filter(e -> e.getParentId() != null && e.getTopParentId() != null && e.getParentId().equals(e.getTopParentId())).collect(Collectors.toList());

        List<NodeEntity> nodeEntityListThree = nodeEntityList.stream().filter(e -> e.getParentId() != null && e.getTopParentId() != null && !e.getParentId().equals(e.getTopParentId())).collect(Collectors.toList());

        Map<Long, List<NodeEntity>> threeMap = nodeEntityListThree.stream().collect(Collectors.groupingBy(NodeEntity::getParentId));

        nodeEntityListTwo.forEach(nodeEntity -> {
            nodeEntity.setNodeEntityList(threeMap.getOrDefault(nodeEntity.getId(), null));
        });

        Map<Long, List<NodeEntity>> twoMap = nodeEntityListTwo.stream().collect(Collectors.groupingBy(NodeEntity::getParentId));

        nodeEntityListOne.forEach(nodeEntity -> {
            nodeEntity.setNodeEntityList(twoMap.getOrDefault(nodeEntity.getId(), null));
        });

        Long end = System.currentTimeMillis();
//        for (NodeEntity nodeEntity : nodeEntityListOne) {
//            System.out.println(nodeEntity);
//        }
        long time = end - start;
        System.out.println("nodeAlgorithmTwo is time : " + time);
    }

}
